#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/6/16 17:18
# @Author  : huidong.bai
# @File    : conftest.py
# @Software: PyCharm
# @Mail    : MasterBai2018@outlook.com
import os
import pytest
import pickle
import pdb
import subprocess
import time
import shutil
import signal
import multiprocessing
from Run_Mongo import cmder
from loguru import logger
# mongo日志
logging = logger.opt()
logger.remove()
from src.utils.common import copy_configs, copy_libs, replace_file
from src.utils.file_reader import FileReader
from src.utils.common import async_color_print
from pathlib import Path


@pytest.fixture(scope="session", autouse=True)
def server_programs(request, pytestconfig):
    # 日志写入文件
    log_format = "{time:YYYY-MM-DD HH:mm:ss} | {level}| {name}:{module}:{line:4} | {message}"
    logging.add(sink=open(f'{cmder.suite_dir}/mongo.log', 'w', encoding='UTF-8'), format=log_format, enqueue=True)
    
    # 解析decoder.conf
    config_reader = FileReader(cmder.config)
    cmder.parse_yaml = config_reader.get_config("ASSERT_PATH_CONFIG")
    cmder.param_event_yaml = config_reader.get_config("PARAM_EVENT_PATH_CONFIG")
    cmder.source_lcs_config = cmder.source_lcs_config if cmder.source_lcs_config else config_reader.get_config("LCS_DECODER_PATH")
    cmder.old_lcs_config = config_reader.get_config("LCS_DECODER_PATH")
    cmder.carplay_config = config_reader.get_config("CARPLAY_SDK_CONF")
    cmder.lang_runner = config_reader.get_config("lang")
    cmder.appid = config_reader.get_config("TSA_APPID")
    cmder.nlu_input_path = config_reader.get_config("MONGO_NLU_INPUT_PATH")
    cmder.nlu_callback_path = config_reader.get_config("MONGO_NLU_CALLBACK_PATH")

    # suite的lib路径
    cmder.lib_path = os.path.join(cmder.suite_dir, 'lib')
    if not os.path.exists(cmder.lib_path):
        os.makedirs(cmder.lib_path)

    # 创建socket端口文件
    cmder.socket_path = os.path.join(cmder.suite_dir, 'ports')
    if not os.path.exists(cmder.socket_path):
        os.makedirs(cmder.socket_path)

    # 创建log文件
    cmder.log_path = os.path.join(cmder.suite_dir, 'log')
    if not os.path.exists(cmder.log_path):
        os.makedirs(cmder.log_path)

    # 拷贝AIBS,SpeechEngine,LCSEngine服务库
    cmder.aibs_client_path = copy_libs(item="jenkins_aibsLibrary", key="client", destination=cmder.lib_path, project=cmder.project)
    cmder.ecnr_path = copy_libs(item="jenkins_aibsLibrary", key="nr", destination=cmder.lib_path, project=cmder.project)
    cmder.carplay_sdk_path = copy_libs(item="jenkins_aibsLibrary", key="carplay", destination=cmder.lib_path, project=cmder.project)

    cmder.server_path = copy_libs(item="jenkins_aibsLibrary", key="server", destination=cmder.lib_path, project=cmder.project)
    cmder.speech_path = copy_libs(item="jenkins_aibsLibrary", key="speechEngine", destination=cmder.lib_path, project=cmder.project)
    cmder.lcs_path = copy_libs(item="jenkins_lcsLibrary", key="lcs", destination=cmder.lib_path, project=cmder.project)

    # Copy LCS,SpeechEngine,AIBS,CarPlayService Configfile
    cmder.lcs_config = copy_configs(source_path=cmder.source_lcs_config, dest_dir=cmder.suite_dir, old="MANGO_SUITE_DIR", new=cmder.suite_dir)
    cmder.carplay_config = copy_configs(source_path=cmder.carplay_config, dest_dir=cmder.suite_dir, old="MANGO_SUITE_DIR", new=cmder.suite_dir)
    cmder.aibs_client_config = cmder.server_config = cmder.speech_config = copy_configs(
        source_path=cmder.config, dest_dir=cmder.suite_dir, old="MANGO_SUITE_DIR", new=cmder.suite_dir)
    replace_file(file=cmder.speech_config, old=cmder.old_lcs_config, new=cmder.lcs_config)

    os.system(f"chmod +x {cmder.lib_path}/*")
    # 启动VR服务
    start_service(request)


def start_service(request):
    brand = cmder.case_header.carType.value if cmder.case_header.carType.value else "0"
    device_name = cmder.case_header.device_name.value if cmder.case_header.device_name.value else None
    if device_name:
        carType = '"{\\"brand\\":\\"%s\\",\\"device_name\\":\\"%s\\"}"' % (brand, device_name)
    else:
        carType = '"{\\"brand\\":\\"%s\\"}"' % brand
    # carType = '"{\\"brand\\":\\"%s\\"}"' % brand
    print(carType)
    if cmder.gdb == "True":
        async_color_print(("\n======================= 当前处于GDB调试模式 =======================", 'red'))
        async_color_print(("请另起三个终端, 执行如下指令进行GDB断点调试模式:", 'red'))
        async_color_print((f"LCS断点:\t\t\ngdb --args {cmder.lcs_path} {cmder.lcs_config} cmn", 'red'))
        async_color_print((f"SpeechEngine断点:\t\ngdb --args {cmder.speech_path} --config {cmder.speech_config} --lang cmn --log_path {cmder.log_path}", 'red'))
        async_color_print((f"AIBSServer断点:\t\t\ngdb --args {cmder.server_path} --config {cmder.server_config} --log_path {cmder.log_path} --lang cmn --car_type {carType}", 'red'))
        async_color_print(("==================================================================", 'red'))
        input("按回车键继续...")
        # 如果只起了一个引擎，自动开启其余的引擎
        # 获取/workspace/solution_filter/FILTER/1/ports下的端口文件
        path = cmder.socket_path
        txt_files = []
        for files in os.listdir(path):
            if files.endswith(".port"):
                txt_files.append(files)
        print("文本文件列表:", txt_files)
        if 'lcs.port' not in txt_files:
            print("正在开启lcs引擎")
            lcs_cmd = f"{cmder.lcs_path} {cmder.lcs_config} cmn"
            lcs_server = start_server(lcs_cmd)
            cmder.lcs_pid = lcs_server
        if 'aibs.port' not in txt_files:
            print("正在开启aibs引擎")
            aibs_server_cmd = f"{cmder.server_path} --config {cmder.server_config} --log_path {cmder.log_path} --lang cmn --car_type {carType}"
            aibs_server = start_server(aibs_server_cmd)
            cmder.aibs_pid = aibs_server
        if 'speech.port' not in txt_files:
            print("正在开启speechengine引擎")
            speech_cmd = f"{cmder.speech_path} --config {cmder.speech_config} --lang cmn --log_path {cmder.log_path}"
            speech_server = start_server(speech_cmd)
            cmder.speech_pid = speech_server
    else:
        lcs_cmd = f"{cmder.lcs_path} {cmder.lcs_config} cmn"
        speech_cmd = f"{cmder.speech_path} --config {cmder.speech_config} --lang cmn --log_path {cmder.log_path}"
        aibs_server_cmd = f"{cmder.server_path} --config {cmder.server_config} --log_path {cmder.log_path} --lang cmn --car_type {carType}"
        lcs_server = start_server(lcs_cmd)
        cmder.lcs_pid = lcs_server
        if cmder.suite_name != "PERFORMANCE_VOICEPRINT":
            speech_server = start_server(speech_cmd)
            cmder.speech_pid = speech_server
        aibs_server = start_server(aibs_server_cmd)
        cmder.aibs_pid = aibs_server
    
    # 在测试会话结束后停止程序
    def finalizer():
        # pdb.set_trace()
        try:
            if aibs_server is not None:
                stop_server(aibs_server)
        except NameError:
            pass  # 忽略未定义的变量

        try:
            if speech_server is not None:
                stop_server(speech_server)
        except NameError:
            pass

        try:
            if lcs_server is not None:
                stop_server(lcs_server)
        except NameError:
            pass

    # 注册停止程序的回调函数
    request.addfinalizer(finalizer)


def start_server(cmd):
    process = subprocess.Popen(cmd, shell=True)
    time.sleep(0.5)
    return process.pid


def stop_server(process):
    os.kill(process, signal.SIGKILL)
